﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */

#region Using
using System;
using System.Collections.Generic;
using System.ServiceModel.DomainServices.Server;
using NetBay.Core.BusinessEntities;
using Rio.Doc.Business.Repository;
using Rio.Applications.Web.Services.BusinessEntities;
using System.Xml;
using System.IO;
using System.Linq;
using Rio.Applications.Web.RioWCFServices;
using Rio.Applications.Web.Helpers;
using Rio.Framework.RioManager;
using System.Configuration;
using NetBay.Core.BusinessEntities.AdvancedSearchCriteria;
using NetBay.Core.Tools;
using NetBay.Core.BusinessEntities.Workflow;
#endregion

namespace Rio.Applications.Web.Services
{
    /// <summary>
    /// Class to handle Business entities in a RIA services
    /// </summary>
    public partial class BusinessEntitiesDomainService : DomainService
    {

        /// <summary>
        /// Retreive all Folders that matches criterias
        /// </summary>
        /// <param name="p_lOrganisationId">Organisation identifier</param>
        /// <param name="p_lFolderTypeId">FolderType identifier</param>
        /// <param name="p_oCriteriaFilter">Association of regular expression to applied into item's values</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<Folder> GetFolders(long p_lOrganisationId, long p_lFolderTypeId, Dictionary<long, string> p_oCriteriaFilter = null)
        {
            
            var l_oRet = new List<Folder>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_oCriteriaFilter<" + p_oCriteriaFilter + ">)...");
                var l_oAllFolders = GetFoldersCore(p_lOrganisationId, p_lFolderTypeId, p_oCriteriaFilter);
                l_oRet = l_oAllFolders.Item1;
            }
            catch (Exception ex)
            {
                var l_oFolder = new Folder("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_oCriteriaFilter<" + p_oCriteriaFilter + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetFolders : " + l_oFolder.FullErrorMessage);
                l_oRet.Add(l_oFolder);
            }
            return l_oRet;
        }

        /// <summary>
        /// Retreive all Folders that matches criterias
        /// </summary>
        /// <param name="p_sSerializedData">Serialized data</param>
        /// <param name="p_lOrganisationId">Organisation identifier</param>
        /// <param name="p_lFolderTypeId">FolderType identifier</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<Folder> GetFoldersForAdvancedSearch(string p_sSerializedData, long p_lOrganisationId, long p_lFolderTypeId)
        {
            var l_oRet = new List<Folder>();
            try
            {
                //Deserialize data
                List<AdvancedSearchCriteriaItem> items = SerializationHelper.Deserialize<List<AdvancedSearchCriteriaItem>>(p_sSerializedData);

                //
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + ">)...");
                var l_oAllFolders = GetFoldersCoreForAdvancedSearch(p_lOrganisationId, p_lFolderTypeId, items);
                l_oRet = l_oAllFolders.Item1;

                //Add nb document
                FolderRepository.AddNbDocument(ref l_oRet, GetUser().UserId, p_lFolderTypeId);

            }
            catch (Exception ex)
            {
                var l_oFolder = new Folder("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_sSerializedData<" + p_sSerializedData + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetFoldersForAdvancedSearch : " + l_oFolder.FullErrorMessage);
                l_oRet.Add(l_oFolder);
            }

            return l_oRet;
        }

        /// <summary>
        /// Update a Folder's index
        /// </summary>
        /// <param name="p_lFolderTypeId">Foldertype identifier</param>
        /// <param name="p_lFolderId">Folder identifier</param>
        /// <param name="p_sDocumentIdentifier">The document identifier.</param>
        /// <param name="p_dicIndexValue">Valorization of index</param>
        /// <returns>a ReturnBoolean object</returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<ReturnBoolean> UpdateFolderIndex(long p_lFolderTypeId, long p_lFolderId,  Dictionary<string, string> p_dicIndexValue)
        {
            var l_oReturnObjects = new List<ReturnBoolean>();

            try
            {
                // Add a historic of user action
                AddActionHistoric((int)Constant.UserActions.MODIFICATION_INDEX, p_lFolderTypeId, p_lFolderId, null, null);

                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lFolderTypeId<" + p_lFolderTypeId + "> p_lFolderId<" + p_lFolderId + "> p_dicIndexValue.count<" + p_dicIndexValue.Count + ">)...");
                FolderRepository.UpdateFolderIndex(p_lFolderTypeId, p_lFolderId, p_dicIndexValue);

                // Call workflow Controller 
                WorkflowController.StartWorkflowDispatcher(p_lFolderTypeId, p_lFolderId, wkfConditionType.UpdateIndex, GetUser().UserId);
            }
            catch (Exception ex)
            {
                var l_oReturnObject = new ReturnBoolean(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in UpdateFolderIndex : " + ex.Message);
                l_oReturnObjects.Add(l_oReturnObject);
            }
            return l_oReturnObjects;
        }

        /// <summary>
        /// Updates the folder comment.
        /// </summary>
        /// <param name="p_lFolderTypeId">The folder type id.</param>
        /// <param name="p_lFolderId">The folder id.</param>
        /// <param name="p_sDocumentIdentifier">The document identifier.</param>
        /// <param name="p_sValue">The value.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<ReturnBoolean> UpdateFolderComment(long p_lFolderTypeId, long p_lFolderId, string p_sDocumentIdentifier, string p_sValue)
        {
            var l_oReturnBooleans = new List<ReturnBoolean>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lFolderTypeId<" + p_lFolderTypeId + "> p_lFolderId<" + p_lFolderId + "> p_sValue<" + p_sValue + ">)...");

                var l_oRet = FolderRepository.UpdateFolderComment(p_lFolderTypeId, p_lFolderId, p_sValue);
                l_oReturnBooleans.Add(l_oRet);

                // Call workflow Controller 
                WorkflowController.StartWorkflowDispatcher(p_lFolderTypeId, p_lFolderId, wkfConditionType.UpdateFolderNote, GetUser().UserId);
            }
            catch (Exception ex)
            {
                var l_oReturnBoolean = new ReturnBoolean(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in UpdateFolderComment : " + ex.Message);
                l_oReturnBooleans.Add(l_oReturnBoolean);
            }
            return l_oReturnBooleans;
        }

        /// <summary>
        /// Retreive all Folders that matches criterias 
        /// </summary>
        /// <param name="p_lOrganisationId">Organisation identifier</param>
        /// <param name="p_lFolderTypeId">FolderType identifier</param>
        /// <param name="p_lFolderID">Folder ID</param>
        /// <param name="p_sFolderIdentifier"></param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<Folder> GetFolder(long p_lOrganisationId, long p_lFolderTypeId, long p_lFolderID, string p_sFolderIdentifier, List<String> p_oFullTextDocList = null)
        {
            var l_oRet = new List<Folder>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_lFolderID<" + p_lFolderID + ">)...");
                FolderTypeRepository l_oFolderTypeRepository;
                GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);

                var l_oFolder = l_oFolderTypeRepository.GetFolderByFolderId(p_lFolderID, p_sFolderIdentifier);
                if (p_oFullTextDocList != null)
                {
                    l_oFolder.FullTextDocList = p_oFullTextDocList;
                }

                l_oRet.Add(l_oFolder);

                //Add nb document
                FolderRepository.AddNbDocument(ref l_oRet, GetUser().UserId, p_lFolderTypeId);

            }
            catch (Exception ex)
            {
                var l_oFolder = new Folder("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_lFolderID<" + p_lFolderID + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetFolder : " + l_oFolder.FullErrorMessage);
                l_oRet.Add(l_oFolder);
            }
            return l_oRet;
        }


        /// <summary>
        /// Gets the index values by folder type id.
        /// </summary>
        /// <param name="p_lOrganisationId">Organisation identifier</param>
        /// <param name="p_lFolderTypeId">FolderType identifier</param>
        /// <param name="p_oCriteriaFilter">Association of regular expression to applied into item's values</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<OccurenciesByFolderType> GetIndexValuesByFolderTypeId(long p_lOrganisationId, long p_lFolderTypeId, Dictionary<long, string> p_oCriteriaFilter = null)
        {
            var l_oRet = new List<OccurenciesByFolderType>();
            var l_oAllValues = new Dictionary<long, Dictionary<long, List<string>>>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_oCriteriaFilter<" + p_oCriteriaFilter + ">)...");
                var l_oAllFolders = GetFoldersCore(p_lOrganisationId, p_lFolderTypeId, p_oCriteriaFilter);

                // Build the list of values by index for filtered Folders
                l_oAllValues.Add(0, CreateValuesByIndex(l_oAllFolders.Item1));
                // Build the list of values by index for all Folders
                //l_oAllValues.Add(1, CreateValuesByIndex(l_oAllFolders.Item2));
                //A supprimer
                l_oAllValues.Add(1, CreateValuesByIndex(l_oAllFolders.Item1));

                // Dispatch this to an Entity object
                l_oRet.Add(new OccurenciesByFolderType(l_oAllValues));
            }
            catch (Exception ex)
            {
                var l_oFolder = new OccurenciesByFolderType("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_oCriteriaFilter<" + p_oCriteriaFilter + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetIndexValuesByFolderTypeId : " + l_oFolder.FullErrorMessage);
                l_oRet.Add(l_oFolder);
            }
            return l_oRet;
        }

        /// <summary>
        /// Delete a folder and its document
        /// </summary>
        /// <param name="p_lFolderTypeId">Folder Type identifier</param>
        /// <param name="p_sFolderId">Folder identifier</param>
        /// <param name="p_iFolderId">Folder identifier integer</param>
        /// <returns></returns>
        [Query]
        public IEnumerable<ReturnObject> DeleteFolder(long p_lFolderTypeId, string p_sFolderId, long p_iFolderId)
        {
            var l_oReturnObjects = new List<ReturnObject>();

            try
            {
                // Add a historic of user action
                AddActionHistoric((int)Constant.UserActions.SUPRESSION_DOSSIER, p_lFolderTypeId, p_iFolderId, null, null);

                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lFolderTypeId<" + p_lFolderTypeId + "> p_sFolderId<" + p_sFolderId + ">)...");
                FolderRepository.DeleteFolder(p_lFolderTypeId, p_sFolderId);
            }
            catch (Exception ex)
            {
                var l_oReturnObject = new ReturnObject(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in DeleteFolder : " + ex.Message);
                l_oReturnObjects.Add(l_oReturnObject);
            }
            return l_oReturnObjects;
        }

        /// <summary>
        /// For compilation usage. ESSENTIAL! Do Not Delete!
        /// </summary>
        /// <returns></returns>
        [Query]
        public IEnumerable<Folder> oGenerateClass_Folder()
        {
            return new List<Folder> { new Folder() };
        }

        /// <summary>
        /// Check the unicity of index values
        /// </summary>
        /// <param name="p_lFolderTypeId">Folder Type identifier</param>
        /// <param name="p_oCriteriaFilter">List of unique index values</param>
        /// <param name="p_lFolderId">The folder id.</param>
        /// <returns>Return a list of index identifier that not unique</returns>
        [Invoke(HasSideEffects = true)]
        public IEnumerable<long> CheckUnicityOfIndexValue(long p_lFolderTypeId, Dictionary<long, string> p_oCriteriaFilter, long p_lFolderId)
        {
            var l_oRet = new List<long>();
            try
            {
                l_oRet = IndexRepository.CheckUnicityOfIndexValue(p_lFolderTypeId, p_oCriteriaFilter, p_lFolderId);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in CheckUnicityOfIndexValue : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Check if the specified folder identifier allready exist
        /// </summary>
        /// <param name="p_lOrganisationId">Organization identifier</param>
        /// <param name="p_lFolderTypeId">Folder identifier</param>
        /// <param name="p_oIndexValorization">Index</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnLong IsFolderExist(long p_lOrganisationId, long p_lFolderTypeId, Dictionary<long, string> p_oIndexValorization, bool p_bUseAllCriteria = false)
        {
            var l_oRet = new ReturnLong();
            try
            {
                FolderTypeRepository l_oFolderTypeRepository;
                GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);
                
                // Create the list of combination Index and its value
                var l_oDicIndexValorization = RebuildDictionaryIndex(p_oIndexValorization, l_oFolderTypeRepository.LstIndex);
                
                var l_oCurrentUser = GetUser();
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lFolderTypeId<" + p_lFolderTypeId + ">)...");
                l_oRet = FolderRepository.IsFolderExist(l_oCurrentUser.UserId, p_lFolderTypeId, l_oFolderTypeRepository.Table, l_oDicIndexValorization, p_bUseAllCriteria);
                
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnLong(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in IsFolderExist : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Generates the PDF report.
        /// </summary>
        /// <param name="p_lOrganisationId">The P_L organisation id.</param>
        /// <param name="p_sFolderIds">The P_S folder ids.</param>
        /// <param name="p_lFolderTypeId">The P_L folder type id.</param>
        /// <param name="p_oFolderIndex">Index of the p_o folder.</param>
        /// <param name="p_lParagraphIdentifier">The P_L paragraph identifier.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnLong GeneratePDFReport(long p_lOrganisationId, string p_sFolderIds, long p_lFolderTypeId, Dictionary<long,string> p_oFolderIndex, long p_lParagraphIdentifier)
        {
            var l_oRet = new ReturnLong();

            try
            {
                WCFServiceClient m_oWCFRioServices = new WCFServiceClient("BasicHttpBinding_IWCFService");
                var l_oMessageRequest = new MessageRequest();
                l_oMessageRequest.LicenseKey = ConfigurationManager.AppSettings.Get("LicenseKey");
                l_oMessageRequest.EncryptLicense(RioApplicationSettings.LicenseKeyDuration);

                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_lFolderID<" + p_sFolderIds + ">)...");
                FolderTypeRepository l_oFolderTypeRepository;
                GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);
                var l_oFolders = l_oFolderTypeRepository.GetFolderByFolderIds(p_sFolderIds);
                MemoryStream l_oStream = BuildXMLDocument(l_oFolders, p_oFolderIndex, p_lParagraphIdentifier);
                string l_sReportFileName = PostDocument(l_oStream);
                String l_sReportDestinationFileName = String.Format(@"{0}\{1}", @"C:\NetBay\RioScann\TemporaryScannedFiles\Users\110", Path.GetFileNameWithoutExtension(l_sReportFileName) + ".pdf");

                GenerateReportRequest l_oReportRequest = new GenerateReportRequest(GetUser().UserId, l_sReportFileName, l_sReportDestinationFileName, GetUser().Email, l_oMessageRequest);
                m_oWCFRioServices.GenerateReport(l_oReportRequest);

            }
            catch (Exception ex)
            {
                var l_oFolder = new Folder("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_lFolderID<" + p_sFolderIds + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetFolder : " + l_oFolder.FullErrorMessage);
            }
            
            return l_oRet;
        }

        #region Privates
        /// <summary>
        /// Retreive all Folders that matches criterias 
        /// </summary>
        /// <param name="p_lOrganisationId">Organisation identifier</param>
        /// <param name="p_lFolderTypeId">FolderType identifier</param>
        /// <param name="p_oCriteriaFilter">Association of regular expression to applied into item's values</param>
        /// <returns>The cuple of folders filtered and all folders</returns>
        private Tuple<List<Folder>, List<Folder>> GetFoldersCore(long p_lOrganisationId, long p_lFolderTypeId, Dictionary<long, string> p_oCriteriaFilter = null)
        {
            Tuple<List<Folder>, List<Folder>> l_oRet;
            var l_oFolders = new List<Folder>();

            try
            {
                FolderTypeRepository l_oFolderTypeRepository;
                var l_oUser = GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);

                // We must search all folder that matches with criteria filter
                l_oRet = l_oFolderTypeRepository.GetFoldersFilteredByRegularExpressionIntoItems(l_oUser.UserId, p_oCriteriaFilter);

            }
            catch (Exception ex)
            {
                var l_oFolder = new Folder("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_oCriteriaFilter<" + p_oCriteriaFilter + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetFoldersCore : " + l_oFolder.FullErrorMessage);
                l_oRet = Tuple.Create(new List<Folder> { l_oFolder }, l_oFolders);
            }
            return l_oRet;
        }

        /// <summary>
        /// Retreive all Folders that matches criterias 
        /// </summary>
        /// <param name="p_lOrganisationId">Organisation identifier</param>
        /// <param name="p_lFolderTypeId">FolderType identifier</param>
        /// <param name="p_sSerializedData">Association of regular expression to applied into item's values for Advanced Search (serialized)</param>
        /// <returns>The cuple of folders filtered and all folders</returns>
        private Tuple<List<Folder>, List<Folder>> GetFoldersCoreForAdvancedSearch(long p_lOrganisationId, long p_lFolderTypeId, List<AdvancedSearchCriteriaItem> p_oCriteriaFilter)
        {
            Tuple<List<Folder>, List<Folder>> l_oRet;
            var l_oFolders = new List<Folder>();

            try
            {
                FolderTypeRepository l_oFolderTypeRepository;
                var l_oUser = GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);

                // We must search all folder that matches with criteria filter
                l_oRet = l_oFolderTypeRepository.GetFoldersFilteredByRegularExpressionIntoItemsForAdvancedSearch(l_oUser.UserId, p_oCriteriaFilter);

            }
            catch (Exception ex)
            {
                var l_oFolder = new Folder("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetFoldersCoreForAdvancedSearch : " + l_oFolder.FullErrorMessage);
                l_oRet = Tuple.Create(new List<Folder> { l_oFolder }, l_oFolders);
            }
            return l_oRet;
        }

        private static Dictionary<long, List<string>> CreateValuesByIndex(List<Folder> l_oFolders)
        {
            var l_oRet = new Dictionary<long, List<string>>();
            try
            {
                foreach (Folder l_oFolder in l_oFolders)
                {
                    try
                    {
                        // Get enumerator for 'ListIndex'
                        List<Index>.Enumerator l_oEnumeratorIndex = l_oFolder.ListIndex.GetEnumerator();
                        // Get enumerator for 'ListValues'
                        List<string>.Enumerator l_oEnumeratorValue = l_oFolder.ListValues.GetEnumerator();
                        for (int i = 0; i < l_oFolder.ListIndex.Count; i++)
                        {
                            try
                            {
                                // Check end loop
                                if (l_oEnumeratorIndex.MoveNext() == false)
                                    break;
                                if (l_oEnumeratorValue.MoveNext() == false)
                                    break;
                                // Check if value is valid
                                string l_szValue = l_oEnumeratorValue.Current;
                                if (string.IsNullOrEmpty(l_szValue) == false)
                                {
                                    if (string.IsNullOrEmpty(l_szValue.Trim()) == false)
                                    {
                                        // Check if Item Id is already include
                                        if (l_oRet.ContainsKey(l_oEnumeratorIndex.Current.Indentifier) == false)
                                        {
                                            l_oRet.Add(l_oEnumeratorIndex.Current.Indentifier, new List<string>());
                                        }
                                        // Check if Value is already include
                                        if (l_oRet[l_oEnumeratorIndex.Current.Indentifier].Contains(l_oEnumeratorValue.Current) == false)
                                        {
                                            l_oRet[l_oEnumeratorIndex.Current.Indentifier].Add(l_oEnumeratorValue.Current);
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Unable to process Index(" + l_oEnumeratorIndex.Current + ")", ex);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Unable to process Folder(" + l_oFolder + ")", ex);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Unable to create the list of values by index", ex);
            }
            return l_oRet;
        }

        /// <summary>
        /// Add a folder with a list of valorization in a folderType
        /// </summary>
        /// <param name="p_lUserId">User ID</param>
        /// <param name="p_lFolderTypeId">Folder type identifier</param>
        /// <param name="p_szIdDoc">Document ID</param>
        /// <param name="p_szTableNameFolder">Table name of Folder</param>
        /// <param name="p_oIndexValorization">cuple of valorization of index (Index, value of index)</param>
        /// <returns>Retreive the FolderID</returns>
        private ReturnLong AddFolder(long p_lUserId, long p_lFolderTypeId, string p_szIdDoc, string p_szTableNameFolder, Dictionary<Index, string> p_oIndexValorization)
        {
            var l_oReturnLong = FolderRepository.AddFolder(p_lUserId, p_lFolderTypeId, p_szIdDoc, p_szTableNameFolder, p_oIndexValorization);

            // Add a historic of user action
            AddActionHistoric((int)Constant.UserActions.CREATION_DOSSIER, p_lFolderTypeId, l_oReturnLong.Value, p_szIdDoc, null);

            return l_oReturnLong;
        }

        /// <summary>
        /// This method build the XML report
        /// </summary>
        /// <param name="p_ListFolder"></param>
        /// <returns>The stream as byte array</returns>
        private MemoryStream BuildXMLDocument(List<Folder> p_ListFolder, Dictionary<long, string> p_oFolderIndex, long p_lParagraphIdentifier)
        {
            XmlWriterSettings wSettings = new XmlWriterSettings();
            wSettings.Indent = true;
            MemoryStream ms = new MemoryStream();
            XmlWriter xw = XmlWriter.Create(ms, wSettings);// Write Declaration
            xw.WriteStartDocument();

            // Write the root node
            xw.WriteStartElement("export");
            xw.WriteStartAttribute("user");
            xw.WriteString(GetUser().FullName);
            xw.WriteEndAttribute();
            xw.WriteStartAttribute("date");
            xw.WriteString(DateTime.Now.ToShortDateString());
            xw.WriteEndAttribute();

            foreach (Folder l_oFolder in p_ListFolder)
            {

                //Load index and according values in a dictionary
                Tuple<string, string> l_oParagraphTitle = null;
                Dictionary<long, Tuple<string, string>> l_oIndexList = new Dictionary<long, Tuple<string, string>>();
                for (int i = 0; i < l_oFolder.ListIndex.Count; i++)
                {
                    Tuple<string, string> l_oIndex = new Tuple<string, string>(l_oFolder.ListIndex[i].IndexLabel, l_oFolder.ListValues[i]);
                    l_oIndexList.Add(l_oFolder.ListIndex[i].Indentifier, l_oIndex);
                    if (l_oFolder.ListIndex[i].Indentifier == p_lParagraphIdentifier)
                    {
                        l_oParagraphTitle = l_oIndex;
                    }

                }
                                
                // Write the folder
                xw.WriteStartElement("folder");
                xw.WriteStartAttribute("name");
                xw.WriteString(l_oParagraphTitle.Item2);
                xw.WriteEndAttribute();
                xw.WriteStartAttribute("desc");
                xw.WriteString("Nature de l'objet");
                xw.WriteEndAttribute();
                
                    // Write the folder images
                    xw.WriteStartElement("images");

                    List<string> L_oListExtension = new List<string>();
                    

                    //Add the images file extension
                    L_oListExtension.AddRange(from Enum item in EnumHelper.GetValues(typeof(Constant.ImageFileFormat))
                                      select Constant.szGetDescription(item));
                    string[] l_oDocList = l_oFolder.FolderDocList.Split(';');
                    foreach (string l_oDoc in l_oDocList)
                    {
                        if (L_oListExtension.Contains((Path.GetExtension(l_oDoc)).ToLower()))
                        {
                            xw.WriteStartElement("image");
                            xw.WriteStartAttribute("url");
                            string l_sFullFilePath = String.Format(@"{0}\{1}", SettingsManager.cStoreSettings.Parameter_Storage, l_oDoc);
                            xw.WriteString(l_sFullFilePath);
                            xw.WriteEndAttribute();
                            xw.WriteEndElement();
                        }
                    }
                    l_oDocList = null;
                    
                    // Close images
                    xw.WriteEndElement();

                    // Write the folder indexes
                    xw.WriteStartElement("indexes");

                    foreach (KeyValuePair<long, Tuple<string, string>> kvp in l_oIndexList)
                    {
                        if (p_oFolderIndex.ContainsKey(kvp.Key))
                        {
                            xw.WriteStartElement("index");
                            xw.WriteStartAttribute("name");
                            xw.WriteString(kvp.Value.Item1);
                            xw.WriteEndAttribute();
                            xw.WriteStartAttribute("value");
                            xw.WriteString(kvp.Value.Item2);
                            xw.WriteEndAttribute();
                            xw.WriteStartAttribute("total");
                            xw.WriteString("0");
                            xw.WriteEndAttribute();
                            xw.WriteEndElement();
                        }
                    }

                    // Close indexes
                    xw.WriteEndElement();

                
                // End folder
                xw.WriteEndElement();
            }

            // Close the export
            xw.WriteEndElement();
            
            // Close the document
            xw.WriteEndDocument();

            // Flush the write
            xw.Flush();

            //Byte[] buffer = new Byte[ms.Length];
            //buffer = ms.ToArray();
            //string xmlOutput = System.Text.Encoding.UTF8.GetString(buffer);

            return ms;
        }

        /// <summary>
        /// Post File with segment
        /// </summary>
        /// <param name="state"></param>
        private string PostDocument(MemoryStream p_oStream)
        {
            String l_sReportFileName = string.Empty;
            try
            {
                p_oStream.Position = 0;
                WCFServiceClient m_oWCFRioServices = new WCFServiceClient("BasicHttpBinding_IWCFService");
                var l_oMessageRequest = new MessageRequest();
                l_oMessageRequest.LicenseKey = ConfigurationManager.AppSettings.Get("LicenseKey");
                l_oMessageRequest.EncryptLicense(RioApplicationSettings.LicenseKeyDuration);

                //FileInfo L_oDocumentToPost = p_oObject as FileInfo;
                int L_lSizeOfSlice = 1024 * 1024 * 2;
                // Read File
                //FileStream l_fsfileStream = L_oDocumentToPost.OpenRead();
                long l_lLengthOfFile = p_oStream.Length;
                // Process the number of slice
                int TotalSlices = (int)(l_lLengthOfFile / L_lSizeOfSlice + 1);

                // Read the source file into a byte array.
                byte[] l_oOneRawBuffer = new byte[L_lSizeOfSlice];
                int numBytesToRead = (int)p_oStream.Length;
                int l_iSliceId = 0;
                Guid L_Guid = Guid.NewGuid();
                l_sReportFileName = "PDFReport_" + DateTime.Now.Day + DateTime.Now.Month + DateTime.Now.Year + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second + ".xml";

                while (numBytesToRead > 0)
                {
                    int l_iSliceReaded = 0;
                    
                    l_iSliceReaded = p_oStream.Read(l_oOneRawBuffer, 0, (int)L_lSizeOfSlice);
                    
                    // Break when the end of the file is reached.
                    if (l_iSliceReaded == 0)
                        break;
                    // We have a buffer whith a maximum slice amount of byte
                    byte[] l_oOneSliceToSend = new byte[l_iSliceReaded];
                    Buffer.BlockCopy(l_oOneRawBuffer, 0, l_oOneSliceToSend, 0, l_iSliceReaded);

                    // Determine the final slice
                    bool l_bBoost = false;
                    if (numBytesToRead - l_iSliceReaded <= 0)
                        l_bBoost = true;
                    // Post the slice

                    PostDocumentWithSegmentNoThumbnailRequest ps = new PostDocumentWithSegmentNoThumbnailRequest(l_oOneSliceToSend, l_sReportFileName, GetUser().UserId, L_Guid, l_iSliceId, l_bBoost);
                    m_oWCFRioServices.PostDocumentWithSegmentNoThumbnail(ps);
                    
                    // Decrease the amount of bytes to read
                    numBytesToRead -= l_iSliceReaded;
                    // Increment the slice ID
                    l_iSliceId++;
                }
                // Close to access file
                p_oStream.Close();
                p_oStream.Dispose();
                
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError(String.Format("-------------------- Exception in PostDocument --------------------------- {0} Error : {1} ", DateTime.Now, ex.Message));
            }
            finally
            {
                //remainingWorkItems--;
                //if (remainingWorkItems == 0)
                //{
                //    m_oManuelResetEventList.Set();
                //}
            }

            return l_sReportFileName;

        }

        #endregion
    }


    
}